package com.gmlive.common.gmshare.util;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.text.TextUtils;

import androidx.annotation.Nullable;

import com.facebook.common.executors.CallerThreadExecutor;
import com.facebook.common.references.CloseableReference;
import com.facebook.datasource.DataSource;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.imagepipeline.common.ResizeOptions;
import com.facebook.imagepipeline.core.ImagePipeline;
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber;
import com.facebook.imagepipeline.image.CloseableImage;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * Author: xs
 * Create on: 2020/06/19
 * Description: _
 */
public class BitmapUtil {
    public final static String TAG = BitmapUtil.class.getSimpleName();

    /**
     * 图片加载回调
     */
    public interface BitmapLoadListener {
        void onBitmapLoaded(Bitmap bitmap, String url);
    }

    public static void getResizeBitmapFromUrl(Context context, final String url, final int width, final int height, final BitmapLoadListener bitmapCallBack) {
        if (TextUtils.isEmpty(url) || width < 0 || height < 0) {
            bitmapCallBack.onBitmapLoaded(null, url);
            return;
        }

        String fileName = String.valueOf(url.hashCode());
        String filePath = getNewImagePath(context) + fileName;
        final File pathFile = new File(filePath);
        if (pathFile.exists()) {
            Bitmap bitmap = getBitmapFromDisk(pathFile);
            if (isBitmapAvailable(bitmap)) {
                bitmapCallBack.onBitmapLoaded(bitmap, url);
                return;
            }
        }

        ImageRequest anchorImageRequest = ImageRequestBuilder
                .newBuilderWithSource(Uri.parse(url))
                .setResizeOptions(new ResizeOptions(width, height))
                .build();

        ImagePipeline anchorImagePipeline = Fresco.getImagePipeline();
        DataSource<CloseableReference<CloseableImage>>
                anchorDataSource = anchorImagePipeline.fetchDecodedImage(anchorImageRequest, context);
        anchorDataSource.subscribe(new BaseBitmapDataSubscriber() {

                                       @Override
                                       public void onNewResultImpl(@Nullable Bitmap bitmap) {
                                           if (BitmapUtil.isBitmapAvailable(bitmap)) {
                                               Bitmap resultBitmap = Bitmap.createBitmap(bitmap);
                                               bitmapCallBack.onBitmapLoaded(resultBitmap, url);
                                               //保存到本地
                                               saveBitmapToDisk(pathFile, resultBitmap, true);
                                           }
                                       }

                                       @Override
                                       public void onFailureImpl(DataSource dataSource) {
                                           bitmapCallBack.onBitmapLoaded(null, url);
                                       }
                                   },
                CallerThreadExecutor.getInstance());
    }

    /**
     * 从本地获取bitmap
     */
    public static Bitmap getBitmapFromDisk(File file) {
        FileInputStream fis = null;
        Bitmap bitmap = null;
        try {
            if (file.exists()) {
                fis = new FileInputStream(file);
                bitmap = BitmapFactory.decodeStream(fis);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } catch (OutOfMemoryError error) { // 这里是有可能内存溢出的
            error.printStackTrace();
            return null;
        } finally {
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return bitmap;
    }

    public static synchronized void saveBitmapToDisk(File file, Bitmap bitmap, boolean deleteFileIfExist) {
        if (!isBitmapAvailable(bitmap)) {
            return;
        }
        if (deleteFileIfExist && file.exists()) {
            deleteFile(file);
        }
        try {
            FileOutputStream out = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
            out.flush();
            out.close();
        } catch (Throwable e) {
            e.printStackTrace();
            deleteFile(file);
        }
    }

    /**
     * 判断bitmap是否可用 不能为空 不能是已经被回收的 isRecycled返回false
     */
    public static boolean isBitmapAvailable(Bitmap bitmap) {
        // 如果为null或者是已经回收了的就证明是不可用的
        return null != bitmap && !bitmap.isRecycled();
    }

    private static void deleteFile(File file) {
        file.delete();
    }

    /**
     * 初始化应用存储根目录路径"GmLive"
     */
    private static String getNewImagePath(Context context) {
        return context.getCacheDir().getAbsolutePath() + File.separator + "Share"+ File.separator;
    }
}
